package com.tanhua.server.service;


import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.autoconfig.template.SmsTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.commons.utils.JwtUtils;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.model.domain.User;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import com.tanhua.model.vo.ErrorResult;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: cl
 * @Date: 2022/4/29 - 04 - 29
 * @Description:
 */
@Slf4j
@Service
public class UserService {

    //redis中的code名字
    private static final String CODE = "CHECK_CODE_";

    //注入发动短信工具类
    @Autowired
    private SmsTemplate smsTemplate;

    //注入redis
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    //注入远程调用用到的微服务
    @DubboReference
    private UserApi userApi;

    //环信即时通讯
    @Autowired
    private HuanXinTemplate huanXinTemplate;

    //校验冻结服务
    @Autowired
    private UserFreezeService userFreezeService;

    //mq工具类
    @Autowired
    private MqMessageService mqMessageService;


    /**
     * 用户登录(发送验证码)
     *
     * @param phone
     */
    public void sendCode(String phone) {

        //校验登录是否被冻结
        User byMobile = userApi.findByMobile(phone);
        if (byMobile != null) {
            userFreezeService.checkUserStatus(1, byMobile.getId());
        }

        //1、生成随机验证码
        //String code = RandomStringUtils.randomNumeric(6);
        //log.info("code = {} ", code);
        String code = "123456";

        //2、调用阿里云发送验证码
        //smsTemplate.sendSms(phone,code);

        //3、讲验证码存放在redis中
        redisTemplate.opsForValue().set(CODE + phone, code, Duration.ofMinutes(5));

    }

    /**
     * 用户登录(校验登录)
     *
     * @param phone
     * @param code
     * @return
     */
    public Map loginVerification(String phone, String code) {
        //1、从redis中获取存入的验证码
        String redisCode = redisTemplate.opsForValue().get(CODE + phone);

        //2、判断验证码
        if (StringUtils.isEmpty(redisCode) || !code.equals(redisCode)) {
            //throw new RuntimeException("验证码校验失败");
            throw new BusinessException(ErrorResult.loginError());
        }

        //验证码正确，删除redis中的验证码
        redisTemplate.delete(CODE + phone);

        //3、判断是不是新用户(老用户直接登录，新用户需要添加到数据库)
        boolean isNew = false;
        User user = userApi.findByMobile(phone);
        String type = "0101";
        if (user == null) {
            type = "0102";
            user = new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
//            user.setCreated(new Date(System.currentTimeMillis()));
//            user.setUpdated(new Date(System.currentTimeMillis()));
            Long id = userApi.save(user);
            user.setId(id);
            isNew = true;

            //注册成功，分配环信账号和密码
            String hxUser = "hx" + user.getId();
            //环信创建用户
            Boolean b = huanXinTemplate.createUser(hxUser, Constants.INIT_PASSWORD);
            if (b) {
                //上传环信账户密码到数据库user表
                user.setHxUser(hxUser);
                user.setHxPassword(Constants.INIT_PASSWORD);
                userApi.update(user);
            }
        }

        //发送mq消息
        mqMessageService.sendLogMessage(user.getId(), type, "user", null);

        //4、登录成功，生成token返回给前端(验证用户是否登录要用)
        HashMap<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("id", user.getId());
        tokenMap.put("mobile", phone);
        String token = JwtUtils.getToken(tokenMap);

        //5、封装token并返回
        HashMap<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("isNew", isNew);

        return result;
    }

    /**
     * 修改手机号
     *
     * @param user
     */
    public void update(User user) {

        //查询数据库看手机号是否已经存在
        User byMobile = userApi.findByMobile(user.getMobile());
        if (byMobile != null) {
            //如果存在，抛出异常
            throw new BusinessException(ErrorResult.mobileError());
        }
        //如果不存在就正常保存修改
        userApi.update(user);
    }

    /**
     * 校验验证码
     *
     * @param mobile
     * @param verificationCode
     * @return
     */
    public boolean check(String mobile, String verificationCode) {
        //1、从redis中获取存入的验证码
        String redisCode = redisTemplate.opsForValue().get(CODE + mobile);
        //2、判断验证码
        if (StringUtils.isEmpty(redisCode) || !verificationCode.equals(redisCode)) {
//            //throw new RuntimeException("验证码校验失败");
//            throw new BusinessException(ErrorResult.loginError());
            return false;
        } else {
            //验证码正确，删除redis中的验证码
            redisTemplate.delete(CODE + mobile);
            return true;
        }
    }
}
